
class Student {
    //方法属性、字段、方法变量
    private String name;
    private int age;
    public static String classRoom;
    //构造方法
    public Student(String name,int age) {
        this.name = name;
        this.age = age;
    }
    //获取方法属性、变量、字段的方法
    public String getName() {
        return name;
    }
    public int getAge() {
        return age;
    }
    public static String getClassRoom() {
        return classRoom;
    }
    public void setName(String name) {
        this.name = name;
    }
    public void setAge(int age) {
        this.age = age;
    }
//    public static void setClassRoom(String classRoom) {//因为classRoom是静态变量，所以使用this引用会报警告
//        classRoom = classRoom;
//    }
    //成员方法、行为
    public void eat() {
        System.out.println(this.name + "正在吃饭.....");
    }
    public static void sleep() {
        System.out.println("正在睡觉....");
    }
}
class TestStatic {
    public int num1 = 10;
    public static int num2 = 9;

    //静态代码块
    static {
        num2 = 99;
        System.out.println("执行了静态代码块....");
    }

    static {//类被加载就会被执行
        num2 = 999;
        System.out.println("执行了静态代码块....");
    }
    //构造代码块/实例代码块
    {//new 对象时会被执行
        num1 = 100;
        System.out.println("执行了实例化代码块....");
    }
    //构造方法
    public TestStatic() {
        System.out.println("执行了构造方法....");
    }
    public static void main(String[] args) {
        System.out.println(num2);
        TestStatic testStatic = new TestStatic();
        System.out.println(testStatic.num1);
        //普通代码块
        {
            int num1 = 20;
            System.out.println("执行了普通代码块....");
        }
        //1.普通代码块/局部代码块{}
        //定义在方法当中，永远会被执行
        //2.静态代码块 static {}
        //2.1最先执行静态代码块、只要类被加载就会执行静态代码块
        //2.2静态代码块内不能初始化对象属性，但实例代码块可以初始化或定义静态属性
        //2.3静态代码块只执行一次
        //2.4静态代码块定义有先后关系，如果一个类中包含多个静态代码块，在编译代码时，编译器会按照定义的先后次序依次执行(合并)
        //3.实例化代码块
        //3.1 只有new 对象时才能执行
        //3.2 一般用于初始化成员变量
        //三者先后顺序：静态代码块->实例化代码块->构造方法
    }
}
public class Test {
    public static void main(String[] args) {
        //静态变量/静态方法的初始化
        //1.1就地初始化：定义时直接进行赋值
        //1.2静态代码块初始化
    }
    public static void main4(String[] args) {
        //static成员
        //1.static修饰成员变量：静态成员变量 非静态成员变量/普通成员变量
        //1.1 使用static修饰的变量叫做静态方法变量
        //1.2 使用类名 + 点号进行改变变量，对象.变量也可以做到，但是会有警告，建议使用前一种方法调用
        //1.3 该变量不属于对象，属于类属性，数据可以共享
        //1.4 存储在方法区中
        //1.5 伴随整个生命周期(随着创建而创建，随着销毁而销毁)
        Student.classRoom = "2308";
        Student student1 = new Student("张三",18);
        //student1.classRoom = "2301";//会报警告，因为静态成员变量并不属于对象，而是属于类
        Student student2 = new Student("李四",20);
        Student student3 = new Student("王五",22);
        //2.static修饰成员方法:静态成员方法  非静态成员方法/普通成员方法
        Student.sleep();
        //2.1不属于对象，属于类，可以进行共享
        //2.2成员方法使用类名或对象名进行调用，建议使用成员方法进行调用
        //2.3不能在静态方法中访问任何非静态成员变量
        //2.4静态方法中不能调用任何非静态方法，因为非静态方法有this参数，在静态方法中调用时候无法传递this引用
        //2.5非静态方法可以调用静态变量、静态方法
    }
    public static void main3(String[] args) {
        //访问修饰限定符
        //private:只能在同一包相同类中使用（私有类）
        //default:同一包中，相同类、不同类均可使用(定义时，没有加任何权限修饰限符时，则是default)
        //protected:同一包中，类，不同类中的子类
        //public:无论在任何包均可使(公共类)
    }
    public static void main2(String[] args) {
        //包
        //1.1不同类的集合相当于目录
        //1.2当创建类时，没有指定放于那个包时，会放在一个默认的包内
        //导包
        //2.1想要调用一个包时，使用import在类第一行进行添加包
        //2.2可以使用*号来代替你想要使用功能的同一类下，不同包，
        // 但不建议，因为可能一个相同类可能存在不同包中，如果import不同包，会导致编译器出错
        //自定义包
        //3.1在文件最上方使用package语句指定代码在哪个包中
        //3.2一般自定义包，使用域名倒置的方法(报名全部小写，'.'号隔开)
        //3.3包名要和代码路径相同，一般自定义好包后,创建类文件，会自动添加路径到头
        //静态包
        //可以使用import static 导入方法/字段
        //Math.pow() :可以通过在类外通过 import static java.lang.Math.*; 这样子就可以直接使用pow方法，而不用加Math.
    }
    public static void main1(String[] args) {
        //封装：对方法属性进行隐藏，只能通过类对外开放的接口来和对象交互(套壳屏蔽细节->安全性)
        Student student = new Student("张三",18);
        System.out.println(student.getName());
        System.out.println(student.getAge());
        student.setName("小黑");
        student.setAge(23);
        System.out.println(student.getName());
        System.out.println(student.getAge());
        student.eat();
    }
}
